package felix.rule.service.actors.chain;

import felix.actor.core.TActor;
import felix.actor.core.TActorCtx;
import felix.actor.core.TActorId;
import felix.actor.core.msg.TActorMsg;
import felix.actor.core.msg.TMsgType;
import felix.rule.data.msg.QueueToRuleEngineMsg;
import felix.rule.data.msg.RuleChain;
import felix.rule.data.plugin.ComponentLifecycleMsg;
import felix.rule.service.actors.ActorSystemContext;
import felix.rule.service.actors.ComponentActor;
import felix.rule.service.actors.ContextBasedCreator;
import felix.rule.service.actors.TEntityActorId;
import lombok.extern.slf4j.Slf4j;

import static felix.rule.data.msg.MessageType.*;

@Slf4j
public class RuleChainActor extends ComponentActor<RuleChainActorMessageProcessor> {

    private final RuleChain ruleChain;

    private RuleChainActor(ActorSystemContext systemContext, String tenantId, RuleChain ruleChain) {
        super(systemContext, tenantId, ruleChain.getId());
        this.ruleChain = ruleChain;
    }

    @Override
    protected RuleChainActorMessageProcessor createProcessor(TActorCtx ctx) {
        return new RuleChainActorMessageProcessor(ruleId, ruleChain, systemContext,
                ctx.getParentRef(), ctx);
    }

    @Override
    protected boolean doProcess(TActorMsg msg) {
        TMsgType msgType = msg.getMsgType();
        if (QUEUE_TO_RULE_ENGINE_MSG.equals(msgType)) {
            processor.onQueueToRuleEngineMsg((QueueToRuleEngineMsg) msg);
        } else if (RULE_TO_RULE_CHAIN_TELL_NEXT_MSG.equals(msgType)) {
            processor.onTellNext((RuleNodeToRuleChainTellNextMsg) msg);
        } else if (RULE_CHAIN_TO_RULE_CHAIN_MSG.equals(msgType)) {
            processor.onRuleChainToRuleChainMsg((RuleChainToRuleChainMsg) msg);
        } else if (COMPONENT_LIFE_CYCLE_MSG.equals(msgType)) {
            onComponentLifecycleMsg((ComponentLifecycleMsg) msg);
        } else {
            return false;
        }
        return true;
    }

    @Override
    protected long getErrorPersistFrequency() {
        return systemContext.getRuleChainErrorPersistFrequency();
    }

    public static class ActorCreator extends ContextBasedCreator {
        private static final long serialVersionUID = 1L;

        private final String tenantId;
        private final RuleChain ruleChain;

        public ActorCreator(ActorSystemContext context, String tenantId, RuleChain ruleChain) {
            super(context);
            this.tenantId = tenantId;
            this.ruleChain = ruleChain;
        }

        @Override
        public TActorId createActorId() {
            return new TEntityActorId(ruleChain.getId(), RuleChainActor.class.getSimpleName());
        }

        @Override
        public TActor createActor() {
            return new RuleChainActor(context, tenantId, ruleChain);
        }
    }

}
